package web.admin.shop.product.tabs;

import domain.shop.Product;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import service.facade.admin.ShopAdminService;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

public abstract class AbstractProductRelationsPanel extends Panel {
    List<ProductWrapper> wrappedProducts;
    @SpringBean
    private ShopAdminService adminService;
    private static Logger logger = Logger.getLogger(AbstractProductRelationsPanel.class.getName());

    public AbstractProductRelationsPanel(String id, Long productId, IModel<String> title) {
        super(id);

        Form form = new Form("form") {
            @Override
            protected void onSubmit() {
                AbstractProductRelationsPanel.this.onSubmit();
            }
        };
        setOutputMarkupId(true);
        wrappedProducts = new ArrayList<ProductWrapper>();
        for (Product product : adminService.findAllProducts()) {
            if (product.getId().equals(productId)) {
                continue;
            }
            ProductWrapper pWrapper = new ProductWrapper(product);
            if (isContained(product)) {
                pWrapper.setCheck(Boolean.TRUE);
            } else {
                pWrapper.setCheck(Boolean.FALSE);
            }
            wrappedProducts.add(pWrapper);
        }
        // add a nested list view; as the list is nested in the form, the form will
        // update all FormComponent childs automatically.
        ListView listView = new ListView("productsList", wrappedProducts) {

            protected void populateItem(ListItem item) {
                ProductWrapper wrapper = (ProductWrapper) item.getModelObject();
                item.add(new Label("productName", new PropertyModel<String>(wrapper, "product.name")));
                item.add(new Label("productId", new PropertyModel<String>(wrapper, "product.id")));
                item.add(new CheckBox("productsSelected", new PropertyModel(wrapper, "selected")));
            }
        };
        add(new Label("title", title));
        form.add(new Label("legend", title));
        listView.setReuseItems(true);
        form.add(listView);
        add(form);
    }

    abstract void onSubmit();

    /**
     * Find if entry product is component of main product
     *
     * @param product - wrapping product
     * @return true if it is component
     */
    abstract boolean isContained(Product product);


    class ProductWrapper implements Serializable {

        private Long productId;
        private Boolean selected;
        private transient Product product;

        public ProductWrapper(Product product) {
            this.productId = product.getId();
        }

        public Boolean isCheck() {
            return selected;
        }

        public void setCheck(Boolean selected) {
            this.selected = selected;
        }

        public Long getProductId() {
            return productId;
        }

        public Product getProduct() {
            if (product == null) {
                return product = adminService.findProductById(productId);
            }
            return product;
        }
    }
}
